#pragma once
#include "AsyncLogger.h"
#include <unordered_map>

namespace mylog
{
    class LoggerManager 
    {
    public:
        static LoggerManager& GetInstance()
        {
            static LoggerManager eton;
            return eton;
        }

        bool loggerExist(const std::string& name)
        {
            std::unique_lock<std::mutex> lock(mtx_);
            auto it =  loggers_.find(name);
            if (it == loggers_.end())
                return false;
            return true;
        }

        void addLogger(const AsyncLogger::ptr&& asyncLogger)
        {
            if (loggerExist(asyncLogger->name()))
                return;
            std::unique_lock<std::mutex> lock(mtx_);
            loggers_.insert(std::make_pair(asyncLogger->name(), asyncLogger));
        }

        AsyncLogger::ptr getLogger(const std::string& name)
        {
            std::unique_lock<std::mutex> lock(mtx_);
            auto it = loggers_.find(name);
            if (it == loggers_.end())
                return AsyncLogger::ptr();
            return it->second;
        }

        AsyncLogger::ptr defaultLogger() 
        {
            return default_logger_;
        }
    private:
        LoggerManager()
        {
            auto builder = std::make_unique<LoggerBuilder>();
            builder->buildLoggerName("default");
            builder->buildLoggerFlush<StdoutFlush>();
            builder->buildFormatPattern("[%D{%Y-%m-%d %H:%M:%S}] [%T] [%P] [%C] [%F:%L] %M%n");
            builder->buildLogLevel(LogLevel::value::DEBUG);
            default_logger_ = builder->build();
            loggers_.insert(std::make_pair(default_logger_->name(), default_logger_));
        }

    private:
        std::mutex mtx_; 
        AsyncLogger::ptr default_logger_;
        std::unordered_map<std::string, AsyncLogger::ptr> loggers_;
    };
} // namespace log
